/*
JETware Hands-free Extension provides additional features for Windows Mobile HFP support.
Copyright (C) 2004-2009 Jim Thatcher

This program is free software; you can redistribute it and/or modify it under the terms of the 
GNU General Public License as published by the Free Software Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; 
if not, write to the Free Software Foundation, Inc., 
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

Source Control header

$Workfile: PhonebookTransfer.cpp $
$Revision: 1 $
$Date: 1/1/09 1:11p $
*/
#include "JetBTConfig.h"
#include "ContactVCard.hpp"
#include "atlbase.h"
#include "obex.h"
#include "ObexClient.hpp"

DWORD	g_dwNumbersPerCard = 0;
DWORD	g_dwNumbersPerContact = 0;
DWORD	g_dwFNFormat = FILE_AS;
DWORD	g_dwMaxNameLen = 0;
DWORD	g_dwEncode = CHARSET_UTF8;

BOOL CALLBACK BeamOptionsDialogProc(const HWND hDlg, const UINT uiMessage, const WPARAM wParam, const LPARAM lParam);

// Support for ObEx send of selected contacts
BOOL BeamFile(HWND hParent, TCHAR * szFilename, DWORD dwCount)
{
#ifdef DEBUG
	CHAR szLog[200];
#endif
	BOOL bRet = FALSE;
	ObexClient * pClient = new ObexClient();
	// Find address of first HFP device
	// TODO: check to see if currently connected
	bt_addr hfpDevice = 0;
	TCHAR szValue[128];
	HKEY hKey;
	DWORD dwSize = 0;
	DWORD dwType = 0;
	// Read currently connected HF device name from registry
	wsprintf(szValue, _T("%ls\\1"), RK_AUDIO_GATEWAY_DEVICES);
#ifdef DEBUG
	sprintf(szLog, "Trying to send %ls", szFilename);
	LogString(szLog);
#endif
    if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, szValue, 0, 0, &hKey))
	{
		// Get Address from first device in AudioGateway Device list
		dwSize = sizeof(hfpDevice);
		RegQueryValueEx(hKey, _T("Address"), NULL, &dwType, (LPBYTE) &hfpDevice, &dwSize);
		if (dwSize && (dwType == REG_BINARY))
		{
			wsprintf(szValue, _T("SOFTWARE\\Microsoft\\Bluetooth\\device\\%4.4X%8.8X"),
				GET_NAP(hfpDevice), GET_SAP(hfpDevice));
			RegCloseKey(hKey);
		}
		if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, szValue, 0, 0, &hKey))
		{
			dwSize = sizeof(szValue);
			dwType = 0;
			szValue[0] = 0;
			RegQueryValueEx(hKey, _T("name"), NULL, &dwType, (LPBYTE) &szValue, &dwSize);
			if (dwSize && (dwType == REG_SZ))
			{
#ifdef DEBUG
				sprintf(szLog, "Found HFP device %ls", szValue);
				LogString(szLog);
#endif
			}
		}
	}
	if (hKey != NULL)
		RegCloseKey(hKey);

	SetCursor(NULL);
    TCHAR szMsg[256];
	if (szValue[0] != 0)
	{
        wsprintf(szMsg, _T("Press Yes to send %i contacts to %ls. Press No to cancel. Make sure your device is ready to receive your phonebook."), dwCount, szValue);
		int nRet = MessageBox(hParent, szMsg, _T("Send phonebook now?"), MB_YESNO);
		if (nRet == IDNO)
			return FALSE;
	}
#ifdef DEBUG
	sprintf(szLog, "Attempting to connect to %4.4X %8.8X", GET_NAP(hfpDevice), GET_SAP(hfpDevice));
	LogString(szLog);
#endif
	if (pClient->Connect(hfpDevice))
	{
		SetCursor(LoadCursor(NULL, IDC_WAIT));
		if (pClient->Put(szFilename))
		{
			bRet = TRUE;
			SetCursor(NULL);
		}
		else
		{
			SetCursor(NULL);
            wsprintf(szMsg, _T("Unable to send contacts to %ls."), szValue);
			MessageBox(hParent, szMsg, _T("Send phonebook failed"), MB_OK);
		}
		pClient->Disconnect();
	}
	else
	{
        wsprintf(szMsg, _T("Unable to connect to %ls. Make sure it is ready to receive contacts via Bluetooth."), szValue);
		MessageBox(hParent, szMsg, _T("Send phonebook failed"), MB_OK);
	}
	delete pClient;
	return (bRet);
}

// void AddContactsToIRFolder(IFolder * pIR)
void SendSelectedContacts(HWND hDlg)
{
	// IFolder *pIR;
	DWORD dwSelectedCount = 0;
	int nCurrOlRecord = 1;
	int nMaxNumbers = 11;
#ifdef DEBUG
	CHAR szLog[512];
#endif
	GetRegSettings();
	// Get settings for ObEx transfer
	int nResult = DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_SENDCONTACTS), hDlg, (DLGPROC)BeamOptionsDialogProc, (LPARAM) NULL);
	if (nResult == IDCANCEL)
		return;
	SetCursor(LoadCursor(NULL, IDC_WAIT));
	// Initialize POOM, get first contact info
	if (InitializeOutlook())
	{
		// g_polApp->GetDefaultFolder(olFolderInfrared, &pIR);
		// Open the Contacts folder
		IPOutlookItemCollection * pItemCol = NULL;

		if (SUCCEEDED(g_pContactsFolder->get_Items(&pItemCol)))
		{
			IContact * pContact = NULL;
	        HANDLE hVcFile = NULL;
	        TCHAR szPath[MAX_PATH];
	        DWORD dwRet;

	        dwRet = GetModuleFileName(NULL, szPath, MAX_PATH);

	        if (dwRet)
	        {
		        TCHAR  *cSlash = wcsrchr(szPath, '\\');
		        *cSlash = 0;
		        lstrcat(szPath, L"\\pb.vcf");
	        }
	        else
	        {
		        BOOL bRet = SHGetSpecialFolderPath(NULL, szPath, CSIDL_PROGRAM_FILES, FALSE);
		        lstrcat(szPath, L"\\JETware\\pb.vcf");
	        }
			hVcFile = CreateFile(szPath, GENERIC_WRITE | GENERIC_READ, 0,
				NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

            while (nCurrOlRecord <= g_nNumContacts)
			{
#ifdef DEBUG_VCF
				sprintf(szLog, "Attempting to open contact %i", nCurrOlRecord);
				LogString(szLog);
#endif
				if (SUCCEEDED(pItemCol->Item (nCurrOlRecord, reinterpret_cast<IDispatch**>(&pContact))))
				{
					int nNumsReturned = 0;
					BSTR bstrCategories;
					BOOL bMatchContact = TRUE;
					BSTR bstrFileAs;
#ifdef DEBUG_VCF
					LogString("Opened next contact");
#endif
				
					// grab properties
					pContact->get_Categories(&bstrCategories);
					pContact->get_FileAs(&bstrFileAs);
#ifdef DEBUG_VCF
					sprintf(szLog, "Checking contact %ls", bstrFileAs);
					LogString(szLog);
#endif

					if ((g_szContactFilter != NULL) || (g_bIncludeNoCat))
					{
						TCHAR * pCurrCat = NULL;
						TCHAR szMarkers[] = {',',';',0};
						bMatchContact = FALSE;
						// run through the categories for this contact
						pCurrCat = _tcstok(bstrCategories, szMarkers);
						if ((pCurrCat == NULL) && g_bIncludeNoCat)
						{
							bMatchContact = TRUE;
#ifdef DEBUG_VCF
							LogString("Matched no category");
#endif
						}
						while (pCurrCat != NULL)
						{
							// loop through each category in the filter list
							TCHAR * pCurrFilterCat = g_szContactFilter;
							TCHAR * pDelim = wcschr(pCurrFilterCat, ',');
							if (*pCurrCat == _T(' '))
								pCurrCat++;
							int nCatLen = wcslen(pCurrCat);
							int nFilterLen = 0;
							while(TRUE)
							{
								nFilterLen = (pDelim != NULL) ? ((pDelim - pCurrFilterCat)) : wcslen(pCurrFilterCat);
								if (nCatLen == nFilterLen)
								{
									if (_wcsnicmp(pCurrCat, pCurrFilterCat, nCatLen) == 0)
									{
#ifdef DEBUG_VCF
										sprintf(szLog, "Matched category %ls", pCurrCat);
										LogString(szLog);
#endif
										bMatchContact = TRUE;
										break;
									}
								}
								if (pDelim == NULL)
									break;
								pCurrFilterCat = pDelim+1;
								if (*pCurrFilterCat == ' ')
									pCurrFilterCat++;
								pDelim = wcschr(pCurrFilterCat, ',');
							}
							if (bMatchContact)
								break;
							pCurrCat = _tcstok(NULL, szMarkers);
						}
					}

					if (bMatchContact)
					{
						dwSelectedCount++;
#ifdef DEBUG_VCF
						CHAR szLog[256];
						sprintf(szLog, "Adding %ls to list", bstrFileAs);
						LogString(szLog);
#endif
						BSTR bstrNumbers[11];
                        BSTR bstrFirstName;
                        BSTR bstrLastName;
                        BSTR bstrEmail;
                        BSTR bstrStreet[2];
                        BSTR bstrCity[2];
                        BSTR bstrState[2];
                        BSTR bstrZip[2];
                        BSTR bstrCountry[2];
					
						// grab properties
						pContact->get_HomeTelephoneNumber(&bstrNumbers[0]);
						pContact->get_MobileTelephoneNumber(&bstrNumbers[1]);
						pContact->get_BusinessTelephoneNumber(&bstrNumbers[2]);
						pContact->get_CarTelephoneNumber(&bstrNumbers[3]);
						pContact->get_AssistantTelephoneNumber(&bstrNumbers[4]);
						pContact->get_Business2TelephoneNumber(&bstrNumbers[5]);
						pContact->get_Home2TelephoneNumber(&bstrNumbers[6]);
						pContact->get_PagerNumber(&bstrNumbers[7]);
						pContact->get_RadioTelephoneNumber(&bstrNumbers[8]);
						pContact->get_BusinessFaxNumber(&bstrNumbers[9]);
						pContact->get_HomeFaxNumber(&bstrNumbers[10]);

                        pContact->get_FirstName(&bstrFirstName);
                        pContact->get_LastName(&bstrLastName);
                        pContact->get_Email1Address(&bstrEmail);
                        pContact->get_HomeAddressStreet(&bstrStreet[0]);
                        pContact->get_HomeAddressCity(&bstrCity[0]);
                        pContact->get_HomeAddressState(&bstrState[0]);
                        pContact->get_HomeAddressPostalCode(&bstrZip[0]);
                        pContact->get_HomeAddressCountry(&bstrCountry[0]);
                        pContact->get_BusinessAddressStreet(&bstrStreet[1]);
                        pContact->get_BusinessAddressCity(&bstrCity[1]);
                        pContact->get_BusinessAddressState(&bstrState[1]);
                        pContact->get_BusinessAddressPostalCode(&bstrZip[1]);
                        pContact->get_BusinessAddressCountry(&bstrCountry[1]);

                        CContact * pVCardContact = new CContact();
                        if (SysStringByteLen(bstrFileAs) > 0)
                        {
                            pVCardContact->SetFileAs(bstrFileAs);
                        }
				        SysFreeString(bstrFileAs);
                        if (SysStringByteLen(bstrFirstName) > 0)
                            pVCardContact->SetFirstName(bstrFirstName);
                        SysFreeString(bstrFirstName);
                        if (SysStringByteLen(bstrLastName) > 0)
                            pVCardContact->SetLastName(bstrLastName);
                        SysFreeString(bstrLastName);
                        if (SysStringByteLen(bstrEmail) > 0)
                            pVCardContact->SetEmail(bstrEmail);
                        SysFreeString(bstrEmail);
                        if (SysStringByteLen(bstrStreet[0]) > 0) // if Street not set then not a valid address
                        {
                            CAddress * pAddr = new CAddress(ADDR_HOME);
                            pAddr->SetStreet(bstrStreet[0]);
                            if (SysStringByteLen(bstrCity[0]) > 0)
                                pAddr->SetCity(bstrCity[0]);
                            if (SysStringByteLen(bstrState[0]) > 0)
                                pAddr->SetState(bstrState[0]);
                            if (SysStringByteLen(bstrZip[0]) > 0)
                                pAddr->SetZip(bstrZip[0]);
                            if (SysStringByteLen(bstrCountry[0]) > 0)
                                pAddr->SetCountry(bstrCountry[0]);
                            
                            pVCardContact->AddAddress(pAddr);
                        }
                        SysFreeString(bstrStreet[0]);
                        SysFreeString(bstrCity[0]);
                        SysFreeString(bstrState[0]);
                        SysFreeString(bstrZip[0]);
                        SysFreeString(bstrCountry[0]);
                        if (SysStringByteLen(bstrStreet[1]) > 0) // if Street not set then not a valid address
                        {
                            CAddress * pAddr = new CAddress(ADDR_WORK);
                            pAddr->SetStreet(bstrStreet[1]);
                            if (SysStringByteLen(bstrCity[1]) > 0)
                                pAddr->SetCity(bstrCity[1]);
                            if (SysStringByteLen(bstrState[1]) > 0)
                                pAddr->SetState(bstrState[1]);
                            if (SysStringByteLen(bstrZip[1]) > 0)
                                pAddr->SetZip(bstrZip[1]);
                            if (SysStringByteLen(bstrCountry[1]) > 0)
                                pAddr->SetCountry(bstrCountry[1]);
                            
                            pVCardContact->AddAddress(pAddr);
                        }
                        SysFreeString(bstrStreet[1]);
                        SysFreeString(bstrCity[1]);
                        SysFreeString(bstrState[1]);
                        SysFreeString(bstrZip[1]);
                        SysFreeString(bstrCountry[1]);

                        for (int x=nMaxNumbers-1; x >= 0; x--)
						{
							if (SysStringByteLen(bstrNumbers[x]) > 0)
							{
                                CPhone * pPhone = new CPhone(bstrNumbers[x], (NUM_TYPE) x);
                                pVCardContact->AddPhone(pPhone);
							}
							SysFreeString(bstrNumbers[x]);
						}
                        // Write vCard contact to stream
                    	if (hVcFile != INVALID_HANDLE_VALUE)
                        {
							pVCardContact->SetNumbersPerVCard(g_dwNumbersPerCard);
							pVCardContact->SetMaxNumbersPerContact(g_dwNumbersPerContact);
							pVCardContact->SetFnFormat(g_dwFNFormat, g_dwMaxNameLen);
							pVCardContact->SetEncoding(g_dwEncode);
                            pVCardContact->WriteToStream(hVcFile);
                        }
                        delete pVCardContact;
					}
					// clean up
					SysFreeString(bstrCategories);
					pContact->Release();
#ifdef DEBUG_VCF
					LogString("Released contact");
#endif
				}
#ifdef DEBUG
				else
				{
					sprintf(szLog, "Item returned error %8.8X", GetLastError());
					LogString(szLog);
				}
#endif
				nCurrOlRecord++;
			}
			pItemCol->Release();
        	if (hVcFile != INVALID_HANDLE_VALUE)
			{
                CloseHandle(hVcFile);
				BeamFile(hDlg, szPath, dwSelectedCount);
			}
		}
	}
	
	SetCursor(NULL);

	// Release objects
	// pIR->Release();
	return;
}



